package com.soup.faker.wrapper;

import com.soup.faker.api.Generator;
import com.soup.faker.api.Interceptor;

import java.util.List;
import java.util.Objects;

/**
 * “三明治”生成器
 * 新增了拦截器功能，可以在拦截器中对返回值进行赋值或替换
 * 设置钩子方法 initWrapper 和 generate，可以通过扩展 ValueWrapper 类，重写钩子方法，来实现功能的扩展
 * @param <T>
 */
public class SandwichGenerator<T> implements Generator<T> {
    private final Generator<T> generator;
    private final List<Interceptor<T>> interceptors;

    public SandwichGenerator(Generator<T> generator, List<Interceptor<T>> interceptors) {
        Objects.requireNonNull(generator);
        Objects.requireNonNull(interceptors);
        this.generator = generator;
        this.interceptors = interceptors;
    }

    @Override
    public T get() {
        ValueWrapper<T> valueWrapper = initWrapper();
        interceptors.forEach(one -> one.before(valueWrapper));
        try {
            generate(valueWrapper, generator);
            interceptors.forEach(one -> one.afterReturn(valueWrapper, generator));
        } catch (Exception ex) {
            interceptors.forEach(one -> one.throwing(valueWrapper, generator, ex));
        } finally {
            interceptors.forEach(one -> one.after(valueWrapper, generator));
        }
        return valueWrapper.get();
    }

    protected ValueWrapper<T> initWrapper() {
        return new ValueWrapper<>();
    }

    protected void generate(ValueWrapper<T> wrapper, Generator<T> generator) {
        if(wrapper.isEmpty()) {
            wrapper.set(generator.get());
        }
    }

}
